﻿using Awsc.DataAcquisitionSys.Core.Model.Config;
using Awsc.DataAcquisitionSys.Core.Models.ServiceModels;
using Awsc.DataAcquisitionSys.Core.Services.DataAcquisition.DataCollectors;
using NModbus;
using System.Net.Sockets;


namespace Awsc.DataAcquisitionSys.Core.Service.DataAcquisition.DataCollectors
{
    public abstract class ModbusTcpDataCollector : DataCollector
    {
        protected ModbusFactory ModbusFactory { get; set; }
        protected IModbusMaster ModbusMaster { get; set; }
        protected TcpClient TcpClient { get; set; }
        public ModbusTcpDataCollector(DataCollectionContext dataCollectionContext) : base(dataCollectionContext)
        {
            ModbusFactory = new ModbusFactory();
            TcpClient = new TcpClient();
        }
        //public event EventHandler<List<SensorData>> DataRecieved;

        public async override Task CollectSensorDataAsync()
        {
            try
            {
                if (TcpClient.Connected)
                {
                    //修改采集器状态
                    Status = DevStatus.S_OK;
                   await CollectDataInternalAsync();

                }
                else
                {
                    //socket重新连接
                    Status = DevStatus.S_OFFLINE;
                    Connect();
                }
            }
            catch (Exception ex)
            {
                if (TcpClient != null)
                {
                    TcpClient.Close();
                }
                Status = DevStatus.S_ERR;
            }
        }

        protected abstract Task CollectDataInternalAsync();


        public override void Connect()
        {
            try
            {
                TcpClient = new TcpClient();
                TcpClient.Connect(CollectorConfig.IP, CollectorConfig.Port);
                if (TcpClient.Connected)
                {
                    TcpClient.Client.Blocking = true;
                    TcpClient.Client.ReceiveTimeout = 100;

                    ModbusMaster = ModbusFactory.CreateMaster(TcpClient);
                    ModbusMaster.Transport.TransactionIDCheck = false;
                    ModbusMaster.Transport.ReadTimeout = 2000;
                    ModbusMaster.Transport.Retries = 10;
                }
            }
            catch (Exception ex)
            {
                Status = DevStatus.S_ERR;
            }
        }
        public override void CloseConnection()
        {
            if (ModbusMaster != null)
            {
                if (TcpClient != null)
                {
                    TcpClient.Client.Close();
                    TcpClient.Close();
                }
                TcpClient = null;
                ModbusMaster.Dispose();
            }
        }


    }
}
